﻿using System;
using System.Devices;
using System.IO;
using System.Reflection;
using System.Threading;
using CommandExecutor;
using RemoteWinceExecutor.Ce.Commands;

namespace RemoteWinceExecutor
{
    public class RemoteDevice
    {
        private RCClient client = new RCClient("169.254.2.1");

        public void Init()
        {
            try
            {
                client.ExecuteCommand<String, bool>("ShutdownServer", "");
                Thread.Sleep(5000);
            }
            catch (Exception e)
            {
            }
            CopyResourceToRemote("RemoteWinceExecutorClient.CommandExecutor.Ce.dll", @"\CommandExecutor.Ce.dll");
            CopyResourceToRemote("RemoteWinceExecutorClient.RemoteWinceExecutorServer.exe", @"\RemoteWinceExecutorServer.exe");
            CopyResourceToRemote("RemoteWinceExecutorClient.Newtonsoft.Json.Compact.dll", @"\Newtonsoft.Json.Compact.dll");
            CopyResourceToRemote("RemoteWinceExecutorClient.OpenNETCF.Configuration.dll", @"\OpenNETCF.Configuration.dll");
            CopyResourceToRemote("RemoteWinceExecutorClient.OpenNETCF.dll", @"\OpenNETCF.dll");
            CopyResourceToRemote("RemoteWinceExecutorClient.OpenNETCF.WindowsCE.dll", @"\OpenNETCF.WindowsCE.dll");
            CopyResourceToRemote("RemoteWinceExecutorClient.OpenNETCF.WindowsCE.Messaging.dll", @"\OpenNETCF.WindowsCE.Messaging.dll");
        }

        private static void CopyResourceToRemote(String resourceName, String remoteFileName)
        {
            var devices = new RemoteDeviceManager().Devices;
            var fileName = Path.GetTempPath() + Guid.NewGuid();
            var ce = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
            var f = File.OpenWrite(fileName);
            CopyStream(ce, f);
            f.Close();
            RemoteFile.CopyFileToDevice(devices.FirstConnectedDevice, fileName, remoteFileName, true);
        }

        public static void CopyStream(Stream input, Stream output)
        {
            byte[] buffer = new byte[8 * 1024];
            int len;
            while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                output.Write(buffer, 0, len);
            }
        }

        public void Reset()
        {
            var res = ExecuteCommand<RebootType, Boolean>("Reboot", RebootType.Soft);
            if (!res)
            {
                throw new Exception("");
            }
        }

        public bool IsPresent
        {
            get { return ExecuteCommand<String, String>("ToLowerCase", "HELLO !").Equals("hello !"); }
        }

        public String ToLowerCase(string s)
        {
            return ExecuteCommand<String, String>("ToLowerCase", s);
        }

        private TResult ExecuteCommand<T, TResult>(string command, T parameter)
        {
            LaunchRemoteServer();
            return client.ExecuteCommand<T, TResult>(command, parameter);
        }

        public void LaunchRemoteServer()
        {
            new RemoteDeviceManager().Devices.FirstConnectedDevice.CreateProcess(@"\RemoteWinceExecutorServer.exe", "", ProcessCreationFlags.None);
        }
    }
}
